Міністерство освіти та науки України
Національний університет «Львівська політехніка»
кафедра прикладної математики
ЛАБОРАТОРНА РОБОТА №3
з системного програмування на тему:
«Синтаксичний аналіз»
Мета: побудувати граматику, яка породжує запропоновану підмножину мови програмування, визначити типи можливих помилок та форму відповідного повідомлення . Написати програму синтаксичного контролю методом рекурсивного спуску (низхідний аналіз), попередньо застосувавши еквівалентні перетворення граматики (якщо потрібно).
При потребі внести доповнення у підпрограму лексичного аналізу. Написати програму – синтаксичний аналізатор, що отримує на вході – текст вхідної програми на запропонованій підмножині мови програмування (у вхідному файлі), а на виході – повідомлення про наявність синтаксичних помилок у вхідній програмі (можна вести контроль до першої помилки) з інформацією про тип помилки та місце її знаходження. Для виділення чергової лексеми використати підпрограму, розроблену у Лаб. Роботі №2.
Варіант №9.
Завдання:
Розглянути підмножину мови Pascal, у якій є ідентифікатори (довжина – не більше 10 символів), цілі константи (довжина – не більше 6 символів), які використовуються у операторах опису (типи змінних – real , integer,boolean), оператори присвоєння, оператори циклу типу while (умова – логічний вираз, утворений з логічних змінних і відповідних логічних операцій).
Граматика:
S → Program I; [R] T
R → var P
P → Z: Y;{Z: Y;}
Z → I {, I}
Y → Real | Integer | Boolean
T → begin A end.
A → B {;B}
B → V | W | L
V → I := U
W → while G do B
L → begin A end
U → M | M + U | M – U | M or U
M → N | N * M | N / M | N and M
N → I | C | (G) | not N
D → = | < | > | <> | <= | >=
G → U D U | (G)
Де:
S = <Програма>
R = <Розділ описів>
P = <Опис>
Z = <Змінні>
Y = <Тип>
T = <Тіло програми>
A = <Оператори>
B = <Оператор>
V=<Присвоєння>
W = <While>
L = <Блок>
U = <Вираз>
M = <Терм>
N = <Множ>
D = <Відношення>
G = <Логічний вираз>
Код програми:
#include <fstream.h>
#include <string.h>
#include <stdio.h>
#include <iostream.h>
#include <ctype.h>
#include <windows.h>
//*********************Opus Global'nuh zminnuh***********************//
FILE *in;
char *f1 = "input.txt";
char *lex, syn, lit = ' ', ch = 0;
int cl = 9, f = 0, num = 1, id_num = 0;
struct st
{
char *id;
int type;
};
st M_id[100];
//************************Prototupu fynkcij**************************//
int getlit();
int zarezerv(char*);
void scan();
void S();
void R();
void P();
void Z();
void Y();
void T();
void A();
void B();
void V();
void W();
void L();
void U();
void M();
void N();
void G();
void D();
void Vudilutu_Lexemy();
//****************************MAIN***********************************//
void main(void)
{
in=fopen(f1, "r");
S();
if(f) Vudilutu_Lexemy();
else cout<<"\n\nV programi nemae pomulok...\n";
for(int j = 0; j < id_num; j++) cout<<"\n"<<M_id[j].id<<"\t"<<M_id[j].type;
}
//*************************Opus fynkcij******************************//
int getlit()
{
lit = fgetc(in);
if(ch != 0) putchar(ch);
ch = lit;
if(lit >= 'A' && lit <= 'Z') lit -= 'A' - 'a';
switch (lit)
{
case '+': return 3; break;
case '-': return 3; break;
case '*': return 3; break;
case '/': return 3; break;
case ';': return 3; break;
case '(': return 3; break;
case ')': return 3; break;
case ',': return 3; break;
case '.': return 3; break;
case '<': return 4; break;
case ':': return 5; break;
case '=': return 6; break;
case '>': return 7; break;
}
if(isalpha(lit)) return 1;
else if(isdigit(lit))return 2;
else return 9;
}
int zarezerv(char* lex)
{
if (!stricmp(lex,"begin")) {syn ='G';return 1;}
if (!stricmp(lex,"end")) {syn ='N';return 1;}
if (!stricmp(lex,"integer")) {syn ='I';return 1;}
if (!stricmp(lex,"real")) {syn ='R';return 1;}
if (!stricmp(lex,"boolean")) {syn ='L';return 1;}
if (!stricmp(lex,"do")) {syn ='T';return 1;}
if (!stricmp(lex,"while")) {syn ='W';return 1;}
if (!stricmp(lex,"var")) {syn ='V';return 1;}
if (!stri...